@model PackageListViewModel
@{
    ViewBag.Title = String.IsNullOrWhiteSpace(Model.SearchTerm) ? "Packages" : "Packages matching " + Model.SearchTerm;
    ViewBag.SortText = String.IsNullOrWhiteSpace(Model.SearchTerm) ? "recent installs" : "relevance";
    ViewBag.Tab = "Packages";
    ViewBag.BlockSearchEngineIndexing = !String.IsNullOrWhiteSpace(Model.SearchTerm) || Model.PageIndex != 0;
}

@helper AddPackageFilterOption(string optionName, string optionValue, bool isDefault = false)
{
    @AddRadioGroupOption("Package Type", "packagetype", optionName, optionValue, Model.PackageType, isDefault);
}

@helper AddSortByOption(string optionName, string optionValue, bool isDefault = false)
{
    @AddRadioGroupOption("Sort By", "sortby", optionName, optionValue, Model.SortBy, isDefault);
}

@helper AddRadioGroupOption(string ariaSectionLabel, string radioGroupName, string optionName, string optionValue, string optionCompareValue, bool isDefault = false)
{
    <div style="display: flex;">
        <label aria-label="@(ariaSectionLabel): @optionName">
            <input type="radio" name="@radioGroupName" @(string.Equals(optionValue, optionCompareValue, StringComparison.OrdinalIgnoreCase) || (isDefault && optionCompareValue == null) ? "checked" : "") value="@optionValue">
            @optionName
        </label>
    </div>
}

@functions
{
    private const string DefaultPackageType = "";
    private static readonly IReadOnlyDictionary<string, string> UiSupportedPackageTypes = new Dictionary<string, string> (StringComparer.OrdinalIgnoreCase)
    {
        { DefaultPackageType, "All types" },
        { "dependency", "Dependency" },
        { "dotnettool", ".NET tool" },
        { "template" , "Template" },
    };
}

<section role="main" class="container main-container page-list-packages">
    <div class="row clearfix no-margin">
        <div class="col-md-10 no-padding">
            <h1 role="alert">
                @if (String.IsNullOrEmpty(Model.SearchTerm))
                {
                    if (Model.TotalCount == 1)
                    {
                        <text>There is 1 package</text>
                    }
                    else
                    {
                        <text>There are @Model.TotalCount.ToNuGetNumberString() packages</text>
                    }
                }
                else
                {
                    if (Model.TotalCount == 1)
                    {
                        <text>1 package </text>
                    }
                    else
                    {
                        <text>@Model.TotalCount.ToNuGetNumberString() packages </text>
                    }

                    <text>returned for @Html.BreakWord(Model.SearchTerm)</text>
                }
            </h1>
        </div>
        <div class="col-md-2 col-xs-3 col-sm-1 text-align-right no-padding">
            @if (Model.IsAdvancedSearchFlightEnabled)
            {
                <button class="btn-command" data-toggle="collapse" data-target="#advancedSearchPanel" aria-expanded="false" aria-controls="advancedSearchPanel">
                    <i class="ms-Icon @(Model.ShouldDisplayAdvancedSearchPanel ? "ms-Icon--FilterSolid" : "ms-Icon--Filter") ms-fontColor-blue" aria-hidden="true"></i>
                    Filter
                </button>
            }
            else
            {
                <a class="prerel-filter" href="?q=@Uri.EscapeDataString(Model.SearchTerm)@(Model.IncludePrerelease ? "&prerel=false" : "")">@(Model.IncludePrerelease ? "Hide" : "Show") prerelease</a>
            }
        </div>
    </div>
    @if (Model.IsAdvancedSearchFlightEnabled)
    {
        <form method="get" class="row clearfix collapse advanced-search-panel@(Model.ShouldDisplayAdvancedSearchPanel ? " in" : "")" id="advancedSearchPanel">
            @if (Model.PackageType != null && !UiSupportedPackageTypes.ContainsKey(Model.PackageType))
            {
                <div class="row warning-panel">
                    <div class="col-md-12 icon-text alert alert-warning">
                        <i class="ms-Icon ms-Icon--Info" aria-hidden="true"></i>
                        Filtering on unrecognized package type: @Model.PackageType
                    </div>
                </div>
            }
            <div class="row">
                <div class="col-md-2">
                    <fieldset id="packagetype">
                        <legend>Package type</legend>
                        @foreach (var packageType in UiSupportedPackageTypes)
                        {
                            @AddPackageFilterOption(packageType.Value, packageType.Key, isDefault: packageType.Key == DefaultPackageType)    
                        }
                    </fieldset>
                </div>
                <div class="col-md-2">
                    <fieldset id="sortby">
                        <legend>Sort by</legend>
                        @AddSortByOption("Relevance", GalleryConstants.SearchSortNames.Relevance, isDefault: true)
                        @AddSortByOption("Downloads", GalleryConstants.SearchSortNames.TotalDownloadsDesc)
                        @AddSortByOption("Recently updated", GalleryConstants.SearchSortNames.CreatedDesc)
                    </fieldset>
                </div>
                <div class="col-md-2">
                    <fieldset>
                        <legend>Options</legend>
                        <div style="display: flex;">
                            <label aria-label="Options: Include prerelease">
                                <input id="prerel-checkbox" type="checkbox" checked="@Model.IncludePrerelease">
                                Include prerelease
                            </label>
                        </div>
                    </fieldset>
                </div>
            </div>
            <div class="row">
                <div class="col-xs-4 col-sm-3 col-md-2 col-lg-1">
                    <input class="btn btn-primary form-control" type="submit" value="Apply">
                </div>
                <div class="col-xs-4 col-sm-3 col-md-2 col-lg-1">
                    <input id="reset-advanced-search" class="btn btn-link form-control" type="button" value="Reset">
                </div>
            </div>
             <input type="hidden" name="q" value="@Model.SearchTerm">
             <input type="hidden" id="prerel" name="prerel" value="@Model.IncludePrerelease.ToString()">
        </form>
    }
    
    @if (!Model.Items.Any())
    {
        <div class="row">
            <div class="col-xs-12 clearfix">
                <div class="panel panel-default" aria-expanded="true" >
                    <div class="panel-body">
                        NuGet package search works the same on nuget.org, from the NuGet CLI, and within the NuGet Package Manager extension in Visual Studio. <br />
                        Check out our <strong><a href="https://docs.microsoft.com/nuget/consume-packages/finding-and-choosing-packages#search-syntax">Search Syntax</a></strong>.
                    </div>
                </div>
            </div>
        </div>
    }

    <div class="list-packages" role="list">
        @{
            var itemIndex = Model.PageIndex * Model.PageSize;
            var eventName = Model.IsPreviewSearch ? "preview-search-selection" : "search-selection";
        }
        @foreach (var package in Model.Items)
        {
            @Html.Partial("_ListPackage", package, new ViewDataDictionary { { "itemIndex", itemIndex }, { "eventName", eventName } })
            itemIndex++;
        }
    </div>

    <div class="row">
        <div class="col-xs-12 clearfix">
            @ViewHelpers.PreviousNextPager(Model.Pager)
        </div>
    </div>
</section>

@section bottomScripts {
    <script type="text/javascript">
        // Used to track how long the user waited before clicking a search selection.
        var pageLoadTime = Date.now();

        // Used to track how many selections were made on this page. Multiple selections can happen if the user opens
        // a search selection in a new tab, instead of navigating away from this page.
        var sincePageLoadCount = 0;
        @{
            var searchId = Guid.NewGuid().ToString();
            var category = Model.IsPreviewSearch ? "preview-search-page" : "search-page";
            var action = Model.IncludePrerelease ? "search-prerel" : "search-stable";

            // Emit an event representing the search page and the page index. This make it easier for the search selection
            // event to be correlated in Google Analytics.
            <text>
            window.nuget.sendAnalyticsEvent('@category', '@action', @Html.Raw(Json.Encode(Model.SearchTerm)), @Model.PageIndex);
            window.nuget.sendMetric('BrowserSearchPage', @Model.PageIndex, {
                SearchId: '@searchId',
                SearchTerm: @Html.Raw(Json.Encode(Model.SearchTerm)),
                IncludePrerelease: '@Model.IncludePrerelease',
                PageIndex: @Model.PageIndex,
                TotalCount: @Model.TotalCount,
                IsPreviewSearch: '@Model.IsPreviewSearch',
                PackageType: @Html.ToJson(Model.PackageType ?? string.Empty),
                SortBy: @Html.ToJson(Model.SortBy)
            });
            </text>
        }

        $(function () {
            var emitClickEvent = function () {
                var $this = $(this);
                var data = $this.data();
                if ($this.attr('href') && data.track) {
                    window.nuget.sendMetric('BrowserSearchSelection', data.trackValue, {
                        SearchId: '@searchId',
                        SearchTerm: @Html.Raw(Json.Encode(Model.SearchTerm)),
                        IncludePrerelease: '@Model.IncludePrerelease',
                        PageIndex: @Model.PageIndex,
                        TotalCount: @Model.TotalCount,
                        ClickIndex: data.trackValue,
                        PackageId: data.packageId,
                        PackageVersion: data.packageVersion,
                        UseVersion: data.useVersion,
                        SincePageLoadMs: Date.now() - pageLoadTime,
                        SincePageLoadCount: sincePageLoadCount,
                        IsPreviewSearch: '@Model.IsPreviewSearch',
                        PackageType: @Html.ToJson(Model.PackageType ?? string.Empty),
                        SortBy: @Html.ToJson(Model.SortBy)
                    });

                    sincePageLoadCount++;
                }
            };
            $.each($('a[data-track]'), function () {
                $(this).on('mouseup', function (e) {
                    if (e.which === 2) { // Middle-mouse click
                        emitClickEvent.call(this, e);
                    }
                });
                $(this).on('click', function (e) {
                    emitClickEvent.call(this, e);
                });
            });
        });

        $('#prerel-checkbox').on('change', function (event) {
            $('#prerel').val($(event.target).is(':checked'));
        });

        $('#reset-advanced-search').on('click', function () {
            location.href = '?q=@Uri.EscapeDataString(Model.SearchTerm)';
        });
    </script>
}
